package com.wxyzz.cem.interceptor;

import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.wxyzz.cem.enums.LoginRole;
import com.wxyzz.cem.enums.ThreadLocalName;
import com.wxyzz.cem.exception.UserLoginStatusException;
import com.wxyzz.cem.pojo.ClassInfo;
import com.wxyzz.cem.pojo.User;
import com.wxyzz.cem.pojo.enums.ClassStatus;
import com.wxyzz.cem.pojo.enums.UserStatus;
import com.wxyzz.cem.util.ThreadLocalUtil;
import com.wxyzz.cem.util.TokenUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author xclhove
 * 用户拦截器
 */
@Component
public class UserInterceptor extends  ServiceInterceptor {
    /**
     * 在方法上加入该注解即可被该拦截器拦截
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface UserIntercept {
    }
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //如果不是映射到方法，则直接通过
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        
        //方法上有加这个注解，那么就说明这个方法不需要拦截
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        UserIntercept intercept = handlerMethod.getMethod().getAnnotation(UserIntercept.class);
        if (intercept == null) {
            return true;
        }
        
        String token = request.getHeader("Authorization");
        User user = null;
        LoginRole loginRole = null;
        try {
            user = TokenUtil.getFirstAudience(token, User.class);
            user = Db.getById(user.getId(), User.class);
            loginRole = TokenUtil.getSecondAudience(token, LoginRole.class);
        } catch (Exception e) {
            throw new UserLoginStatusException();
        }
        
        if (user == null) {
            throw new UserLoginStatusException();
        }
        
        if (user.getStatus() == UserStatus.DISABLE) {
            throw new UserLoginStatusException("已被禁封");
        }
        
        Integer classId = user.getClassId();
        if (classId != null) {
            ClassInfo classInfo = Db.getById(user.getClassId(), ClassInfo.class);
            if (classInfo.getStatus() == ClassStatus.DISABLE) {
                throw new UserLoginStatusException("班级已被禁封");
            }
        }
        
        if (loginRole != LoginRole.USER) {
            throw new UserLoginStatusException();
        }
        
        boolean validate = TokenUtil.validate(token, user.getPassword());
        if (!validate) {
            throw new UserLoginStatusException();
        }
        
        ThreadLocalUtil.set(ThreadLocalName.USER, user);
        return true;
    }
}
